fix: web-core-wasm triggerEvent & lazy component for special DSL usage#2399
Conversation
… tests for component query evaluation
🦋 Changeset detectedLatest commit: bf1c891 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📝 WalkthroughWalkthroughThis PR introduces event bubble support by adding an Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
packages/web-platform/web-core-e2e/tests/web-core.test.ts (2)
186-188: Minor: Redundantunhandledrejectionlistener pattern.The
unhandledrejectionlistener is added inside everypage.evaluatecall but only captures rejections that occur before the callback resolves. If__QueryComponentalways invokes the callback (even on error), this listener may never trigger. Consider whether this pattern is necessary or if it could be simplified.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web-platform/web-core-e2e/tests/web-core.test.ts` around lines 186 - 188, The unhandledrejection listener added via globalThis.addEventListener('unhandledrejection', ...) inside each page.evaluate is redundant because __QueryComponent appears to always invoke the callback (even on error), so the listener will rarely fire and is added repeatedly; remove the per-evaluation listener and instead rely on the callback path from __QueryComponent to report errors (or add a single global unhandledrejection handler once outside page.evaluate if you need to capture asynchronous rejections not reported by the callback), ensuring you reference and use the existing callback resolution logic for error propagation.
175-241: Good test coverage, but consider adding a test for intentionalnull/undefinedreturns.The two tests cover:
- Absent
processEvalResult→ fallback to original export- Present
processEvalResultreturning a value → use that valueHowever, given the concern raised about the
??operator inLynxViewInstance.ts, consider adding a third test case whereprocessEvalResultintentionally returnsnullorundefinedto verify the expected behavior:📝 Suggested additional test case
test('__QueryComponent with processEvalResult returning null', async ({ page, browserName }) => { test.skip(browserName === 'firefox'); await goto(page); await page.evaluate(() => { (globalThis as any).runtime.processEvalResult = () => null; }); const evalResult = await page.evaluate(async () => { return new Promise((resolve) => { globalThis.addEventListener('unhandledrejection', (e) => { resolve({ error: e.reason?.message ?? String(e.reason) }); }); globalThis.runtime.__QueryComponent( '/resources/mock-component.json', (res: any) => { resolve(res); }, ); }); }); expect(evalResult).toMatchObject({ code: 0 }); // This assertion depends on intended behavior: // If null is a valid intentional return, expect null // If null should fallback, expect { mockResult: 'MOCKED_EVAL_RESULT' } expect((evalResult as any).data.evalResult).toBeNull(); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web-platform/web-core-e2e/tests/web-core.test.ts` around lines 175 - 241, Add a third E2E test in packages/web-platform/web-core-e2e/tests/web-core.test.ts named "__QueryComponent with processEvalResult returning null" that mirrors the existing two tests: skip for firefox, call goto(page), set (globalThis as any).runtime.processEvalResult = () => null before invoking globalThis.runtime.__QueryComponent('/resources/mock-component.json', ...), await the resolved evalResult, and assert code === 0; then assert (evalResult as any).data.evalResult is either null or the original export depending on the intended behavior in LynxViewInstance.ts (choose and document which behavior you expect). Ensure the test also covers undefined by adding a similar case or changing the stub to return undefined to validate both scenarios..changeset/fix-query-component-processevalresult.md (1)
1-5: Changeset description may be misleading.The description says "when
processEvalResultis absent" but the implementation uses??which also triggers whenprocessEvalResultreturnsnullorundefined. If the regression concern inLynxViewInstance.tsis addressed, this description would be accurate.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.changeset/fix-query-component-processevalresult.md around lines 1 - 5, The changeset description is misleading because the code uses the nullish coalescing operator (processEvalResult ?? fallback) which also triggers when processEvalResult returns null or undefined, not only when the symbol is absent; update the changeset text to say "when processEvalResult is absent or returns null/undefined during queryComponent execution" and/or change the implementation in the queryComponent code to use an explicit undefined check (e.g., check processEvalResult === undefined) so only a truly missing value (not null) falls back—refer to processEvalResult, queryComponent, and LynxViewInstance.ts when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/web-platform/web-core/ts/client/mainthread/LynxViewInstance.ts`:
- Around line 249-252: The current assignment uses the nullish coalescing
operator and can overwrite intentional null/undefined returns from
mainThreadGlobalThis.processEvalResult; change the logic in LynxViewInstance
where lepusRootChunkExport is set so it only invokes processEvalResult if
mainThreadGlobalThis.processEvalResult exists and then assigns its return value
directly to lepusRootChunkExport (do not use ?? fallback), i.e., check for
presence of mainThreadGlobalThis.processEvalResult before calling it and let its
result (including null or undefined) be the assigned value.
---
Nitpick comments:
In @.changeset/fix-query-component-processevalresult.md:
- Around line 1-5: The changeset description is misleading because the code uses
the nullish coalescing operator (processEvalResult ?? fallback) which also
triggers when processEvalResult returns null or undefined, not only when the
symbol is absent; update the changeset text to say "when processEvalResult is
absent or returns null/undefined during queryComponent execution" and/or change
the implementation in the queryComponent code to use an explicit undefined check
(e.g., check processEvalResult === undefined) so only a truly missing value (not
null) falls back—refer to processEvalResult, queryComponent, and
LynxViewInstance.ts when making the change.
In `@packages/web-platform/web-core-e2e/tests/web-core.test.ts`:
- Around line 186-188: The unhandledrejection listener added via
globalThis.addEventListener('unhandledrejection', ...) inside each page.evaluate
is redundant because __QueryComponent appears to always invoke the callback
(even on error), so the listener will rarely fire and is added repeatedly;
remove the per-evaluation listener and instead rely on the callback path from
__QueryComponent to report errors (or add a single global unhandledrejection
handler once outside page.evaluate if you need to capture asynchronous
rejections not reported by the callback), ensuring you reference and use the
existing callback resolution logic for error propagation.
- Around line 175-241: Add a third E2E test in
packages/web-platform/web-core-e2e/tests/web-core.test.ts named
"__QueryComponent with processEvalResult returning null" that mirrors the
existing two tests: skip for firefox, call goto(page), set (globalThis as
any).runtime.processEvalResult = () => null before invoking
globalThis.runtime.__QueryComponent('/resources/mock-component.json', ...),
await the resolved evalResult, and assert code === 0; then assert (evalResult as
any).data.evalResult is either null or the original export depending on the
intended behavior in LynxViewInstance.ts (choose and document which behavior you
expect). Ensure the test also covers undefined by adding a similar case or
changing the stub to return undefined to validate both scenarios.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7f49eea9-7bd7-4660-a041-230380a0c687
📒 Files selected for processing (12)
.changeset/add-event-bubble-support.md.changeset/fix-query-component-processevalresult.mdpackages/web-platform/web-core-e2e/resources/mock-component.jsonpackages/web-platform/web-core-e2e/tests/web-core.test.tspackages/web-platform/web-core/binary/client/client.d.tspackages/web-platform/web-core/binary/client/client_bg.wasm.d.tspackages/web-platform/web-core/binary/client_legacy/client.d.tspackages/web-platform/web-core/binary/client_legacy/client_bg.wasm.d.tspackages/web-platform/web-core/src/main_thread/client/element_apis/event_apis.rspackages/web-platform/web-core/tests/element-apis.spec.tspackages/web-platform/web-core/ts/client/mainthread/LynxViewInstance.tspackages/web-platform/web-core/ts/client/mainthread/elementAPIs/WASMJSBinding.ts
Merging this PR will improve performance by 26.99%
Performance Changes
Comparing Footnotes
|
React Example#6951 Bundle Size — 237.89KiB (0%).bf1c891(current) vs 78493b4 main#6942(baseline) Bundle metrics
|
| Current #6951 |
Baseline #6942 |
|
|---|---|---|
0B |
0B |
|
0B |
0B |
|
0% |
0% |
|
0 |
0 |
|
4 |
4 |
|
180 |
180 |
|
71 |
71 |
|
46.4% |
46.4% |
|
2 |
2 |
|
0 |
0 |
Bundle size by type no changes
| Current #6951 |
Baseline #6942 |
|
|---|---|---|
145.76KiB |
145.76KiB |
|
92.13KiB |
92.13KiB |
Bundle analysis report Branch PupilTong:p/hw/fix-lazy-componen... Project dashboard
Generated by RelativeCI Documentation Report issue
React MTF Example#85 Bundle Size — 207.47KiB (0%).bf1c891(current) vs 78493b4 main#76(baseline) Bundle metrics
|
| Current #85 |
Baseline #76 |
|
|---|---|---|
0B |
0B |
|
0B |
0B |
|
0% |
0% |
|
0 |
0 |
|
3 |
3 |
|
174 |
174 |
|
68 |
68 |
|
46.09% |
46.09% |
|
2 |
2 |
|
0 |
0 |
Bundle size by type no changes
| Current #85 |
Baseline #76 |
|
|---|---|---|
111.23KiB |
111.23KiB |
|
96.24KiB |
96.24KiB |
Bundle analysis report Branch PupilTong:p/hw/fix-lazy-componen... Project dashboard
Generated by RelativeCI Documentation Report issue
Web Explorer#8529 Bundle Size — 728.84KiB (+0.03%).bf1c891(current) vs 78493b4 main#8520(baseline) Bundle metrics
Bundle size by type
Bundle analysis report Branch PupilTong:p/hw/fix-lazy-componen... Project dashboard Generated by RelativeCI Documentation Report issue |
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @lynx-js/rspeedy@0.14.0 ### Minor Changes - feat: add `Minify.mainThreadOptions` and `Minify.backgroundOptions` for thread-specific minifier. ([#2336](#2336)) ### Patch Changes - Bump Rsbuild v1.7.4 with Rspack v1.7.10. ([#2384](#2384)) - Updated dependencies \[]: - @lynx-js/web-rsbuild-server-middleware@0.20.0 ## @lynx-js/lynx-bundle-rslib-config@0.3.0 ### Minor Changes - **BREAKING CHANGE**: ([#2370](#2370)) Simplify the API for external bundle builds by `externalsPresets` and `externalsPresetDefinitions`. ### Patch Changes - Preserve the default external-bundle `output.minify.jsOptions` when users set `output.minify: true` in `defineExternalBundleRslibConfig`, so required minifier options are not lost. ([#2390](#2390)) ## @lynx-js/external-bundle-rsbuild-plugin@0.1.0 ### Minor Changes - **BREAKING CHANGE**: ([#2370](#2370)) Simplify the API for external bundle builds by `externalsPresets` and `externalsPresetDefinitions`. ### Patch Changes - Updated dependencies \[[`7b7a0c6`](7b7a0c6)]: - @lynx-js/externals-loading-webpack-plugin@0.1.0 ## @lynx-js/react-rsbuild-plugin@0.14.0 ### Minor Changes - feat: support `optimizeBundleSize` option to remove unused code for main-thread and background. ([#2336](#2336)) - If `optimizeBundleSize` is `true` or `optimizeBundleSize.background` is `true`, `lynx.registerDataProcessors` calls will be marked as pure for the background thread output. - If `optimizeBundleSize` is `true` or `optimizeBundleSize.mainThread` is `true`, `NativeModules.call` and `lynx.getJSModule` calls will be marked as pure for the main-thread output. ### Patch Changes - refactor: remove `modifyWebpackChain` since Rsbuild 2.0 dropped webpack support ([#2397](#2397)) - Updated dependencies \[[`9193711`](9193711)]: - @lynx-js/template-webpack-plugin@0.10.7 - @lynx-js/css-extract-webpack-plugin@0.7.0 - @lynx-js/react-webpack-plugin@0.8.0 - @lynx-js/react-alias-rsbuild-plugin@0.14.0 - @lynx-js/use-sync-external-store@1.5.0 - @lynx-js/react-refresh-webpack-plugin@0.3.5 ## @lynx-js/web-core@0.20.0 ### Minor Changes - **This is a breaking change** ([#2322](#2322)) ## Architectural Upgrade: `web-core-wasm` replaces `web-core` This release marks a major architectural upgrade for the web platform. The experimental, WASM-powered engine formerly known as `web-core-wasm` has been fully stabilized and merged into the main branch, completely replacing the previous pure JS/TS based `web-core` implementation. This consolidation massively improves execution performance and aligns the API boundaries of the Web platform directly with other native Lynx implementations. ### 🎉 Added Features - **Core API Enhancements**: Successfully exposed and supported `__QuerySelector` and `__InvokeUIMethod` methods. - **Security & CSP Compliance**: Added a `nonce` attribute to the iframe's `srcdoc` script execution, strengthening Content Security Policy (CSP) compliance. - **`<lynx-view>` Parameter Enhancements**: - Added the `browser-config` attribute and property to `<lynx-view>`. Development environments can now supply a `BrowserConfig` object (e.g., configuring `pixelRatio`, `pixelWidth`, `pixelHeight`) allowing the `systemInfo` payload to be dynamically configured at the instance level. ### 🔄 Changed Features - **Legacy JSON Backwards Compatibility**: Delivered comprehensive fixes and optimizations to deeply support legacy JSON output templates: - Added support for lazy loading execution mode (`lazy usage`). - Implemented the correct decoding and handling of `@keyframe` animation rules. - Rectified rule scoping matching including scoped CSS, root selectors, and type selectors. - **Ecosystem Migration**: Updated testing and ecosystem applications (such as `web-explorer` and `shell-project`) to migrate away from obsolete fragmented dependencies. The new WASM architecture seamlessly integrates Element APIs and CSS directly inside the core client module, requiring a much simpler initialization footprint. **Before (Legacy `web-core` + `web-elements`):** ```typescript // Required multiple imports to assemble the environment import "@lynx-js/web-core/client"; import type { LynxViewElement as LynxView } from "@lynx-js/web-core"; // Had to manually import separate elements and their CSS import "@lynx-js/web-elements/index.css"; import "@lynx-js/web-elements/all"; const lynxView = document.createElement("lynx-view") as LynxView; // ... ``` **After (New `web-core` unified architecture):** ```typescript // The new engine natively registers Web Components and injects fundamental CSS import "@lynx-js/web-core/client"; import type { LynxViewElement as LynxView } from "@lynx-js/web-core/client"; const lynxView = document.createElement("lynx-view") as LynxView; // ... ``` _(Applications can now drop `@lynx-js/web-elements` entirely from their `package.json` dependencies)._ - **Dependency & Boot Sequence Improvements**: Re-architected module loading pathways. Promoted `wasm-feature-detect` directly to a core dependency, and hardened the web worker count initialization assertions. - **Initialization Optimizations**: Converted `SERVER_IN_SHADOW_CSS` initialization bounds to use compilation-time constant expressions for better optimization. ### 🗑️ Deleted Features & Structural Deprecations - **`<lynx-view>` Parameter Removals**: - Removed the `thread-strategy` property and attribute. Historically, this permitted consumers to toggle between `'multi-thread'` and `'all-on-ui'` modes depending on how they wanted the background logic to be executed. The WASM-driven architecture enforces a consolidated concurrency model, deprecating this `<lynx-view>` attribute entirely. - Removed the `overrideLynxTagToHTMLTagMap` property/attribute. HTML tag overriding mechanism has been deprecated in the new engine. - Removed the `customTemplateLoader` property handler from `<lynx-view>`. - Removed the `inject-head-links` property and attribute (`injectHeadLinks`), which previously was used to automatically inject `<link rel="stylesheet">` tags from the document head into the `lynx-view` shadow root. - **Fragmented Packages Removal**: The new cohesive WASM architecture native to `@lynx-js/web-core` handles cross-thread communication, worker boundaries, and rendering loops uniformly. Consequently, multiple obsolete packages have been completely removed from the workspace: - `@lynx-js/web-mainthread-apis` - `@lynx-js/web-worker-runtime` - `@lynx-js/web-core-server` - `@lynx-js/web-core-wasm-e2e` (transitioned into standard test suites) - Added support for `rpx` unit ([#2377](#2377)) **This is a breaking change** The following Styles has been added to `web-core` ```css lynx-view { width: 100%; container-name: lynx-view; container-type: inline-size; --rpx-unit: 1cqw; } ``` Check MDN for the details about these styles: - <https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/container-name> - <https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/container-type> - <https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries> ### how it works? For the following code ```html <view style="height:1rpx"></view> ``` it will be transformed to ```html <view style="height:calc(1 * var(--rpx-unit))"></view> ``` Therefore you could use any `<length>` value to replace the unit, for example: ```html <lynx-view style="--rpx-unit:1px"></lynx-view> ``` By default, the --rpx-unit value is `1cqw` - Added support for transform `vw` and `vh` unit ([#2377](#2377)) Add `transform-vw` and `transform-vh` attributes and properties on `<lynx-view>`. For the following code ```html <view style="height:1vw"></view> ``` If the `transform-vw` is enabled `<lynx-view transform-vw="true">`, it will be transformed to ```html <view style="height:calc(1 * var(--vw-unit))"></view> ``` Therefore you could use any `<length>` value to replace the unit, for example: ```html <lynx-view style="--vw-unit:1px"></lynx-view> ``` ### Patch Changes - feat(web-core): add `is_bubble` parameter to `common_event_handler` to properly handle non-bubbling events like `window.Event('click', { bubbles: false })`. ([#2399](#2399)) - chore: update readme ([#2380](#2380)) - fix: the output format should be module ([#2388](#2388)) - opt: use opt-level 3 to compile wasm ([#2371](#2371)) - fix(web-core): avoid partial bundle loading and double fetching when fetchBundle is called concurrently for the same url. ([#2386](#2386)) - fix(web-core): fallback to the original export chunk when `processEvalResult` is absent during `queryComponent` execution ([#2399](#2399)) - fix: tokenizing inline style values correctly to support rpx and ppx unit conversion ([#2381](#2381)) This fixes an issue where the `transform_inline_style_key_value_vec` API bypassed the CSS tokenizer, preventing dimension units like `rpx` or `ppx` from being successfully transformed into `calc` strings when specified via inline styles. - feat: add mts lynx.querySelectorAll API ([#2382](#2382)) - fix: mts in lazy component ([#2375](#2375)) - fix: enableJSDataProcessor not work ([#2372](#2372)) - feat: add `ppx` unit support for CSS, transforming to `calc(... * var(--ppx-unit))` directly. ([#2381](#2381)) - Updated dependencies \[]: - @lynx-js/web-worker-rpc@0.20.0 ## @lynx-js/externals-loading-webpack-plugin@0.1.0 ### Minor Changes - **BREAKING CHANGE**: ([#2370](#2370)) Simplify the API for external bundle builds by `externalsPresets` and `externalsPresetDefinitions`. ## @lynx-js/devtool-connector@0.1.1 ### Patch Changes - fix: align GlobalKeys with Android DevToolSettings keys and filter global switch responses ([#2392](#2392)) ## @lynx-js/devtool-mcp-server@0.5.1 ### Patch Changes - Updated dependencies \[[`95fff27`](95fff27)]: - @lynx-js/devtool-connector@0.1.1 ## @lynx-js/react@0.117.1 ### Patch Changes - Update preact version to simplify `setProperty` implementation ([#2367](#2367)) ## @lynx-js/react-umd@0.117.1 ### Patch Changes - Add a new `entry` export to `@lynx-js/react-umd` for reuse by wrapper libraries of `@lynx-js/react`. ([#2370](#2370)) ## create-rspeedy@0.14.0 ### Patch Changes - Add optional Lynx DevTool skill. ([#2421](#2421)) - move Vitest integration to create-rstack extraTools and merge the Vitest templates into a single incremental overlay ([#2408](#2408)) ## @lynx-js/kitten-lynx-test-infra@0.1.2 ### Patch Changes - Updated dependencies \[[`95fff27`](95fff27)]: - @lynx-js/devtool-connector@0.1.1 ## @lynx-js/template-webpack-plugin@0.10.7 ### Patch Changes - use path.posix.format instead of path.format to ensure consistent path separators across platforms ([#2359](#2359)) - Updated dependencies \[[`75960cd`](75960cd), [`518c310`](518c310), [`863469e`](863469e), [`dc18c5c`](dc18c5c), [`7d242f3`](7d242f3), [`62bebcf`](62bebcf), [`75960cd`](75960cd), [`182f568`](182f568), [`1aa051d`](1aa051d), [`6b46f7e`](6b46f7e), [`fcda36a`](fcda36a), [`182f568`](182f568), [`138f727`](138f727), [`138f727`](138f727)]: - @lynx-js/web-core@0.20.0 ## @lynx-js/react-alias-rsbuild-plugin@0.14.0 ## upgrade-rspeedy@0.14.0 ## @lynx-js/web-rsbuild-server-middleware@0.20.0 ## @lynx-js/web-worker-rpc@0.20.0 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary by CodeRabbit
Release Notes
Bug Fixes
queryComponentfallback behavior when processing evaluation results is unavailableTests
Checklist